﻿using myOffice = Microsoft.Office.Interop;
using Microsoft.Office.Core;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using TpBaseObjects.Objects;
using TpTools;
using System.Net.Mail;
using System.Net;
using TpExtensions;
using TpData.Manager;
using TpContracts;



namespace TpMailer {
    public partial class Mailer : Form {

        #region Members

        List<MailObj> mailList;
        bool wordStarted;
        private const string errType = "Err";
        private const string logType = "Log";
        private const string logArea = "TpMailer.Mailer";
        

        enum Rechtsform : int {

        }

        #endregion

        #region Constructor

        public Mailer() {
            try {
                LogDataManager.SaveLog(Contracts.MyUser.UserID, logType, logArea, "Mailer: Start Mailer", false);
                this.mailList = new List<MailObj>();
                InitializeComponent();
                this.wordStarted = Office.WordIsStarted();
                this.chkOpen.Checked = true;
                this.chkOpen.Enabled = false;
            } catch (Exception ex) {
                MessageBox.Show(ex.Message, "Error");
            }
        }

        #endregion

        #region Buttons

        private void btnSourceExcelFile_Click(object sender, EventArgs e) {
            if (openFileDialog1.ShowDialog() == DialogResult.OK) {
                this.txtSourceFile.Text = openFileDialog1.FileName;

            }
        }

        private void btnSourceTemplate_Click(object sender, EventArgs e) {
            if (openFileDialog1.ShowDialog() == DialogResult.OK) {
                this.txtTemplate.Text = openFileDialog1.FileName;

            }
        }

        private void btnTargetPath_Click(object sender, EventArgs e) {
            DialogResult result = folderBrowserDialog1.ShowDialog();
            string path = this.txtTargetPath.Text;
            if (result == DialogResult.OK) {
                this.txtTargetPath.Text = folderBrowserDialog1.SelectedPath;

            }
        }

        private void btnStep1_Click(object sender, EventArgs e) {
            GetMailingData(this.txtSourceFile.Text);
        }

        private void btnStep2_Click(object sender, EventArgs e) {
            CreateWordDocuments();
        }

        private void btnStep3_Click(object sender, EventArgs e) {
            CreatePDFDocuments();
        }

        private void btnStep4_Click(object sender, EventArgs e) {
            SendMails();
        }

        #endregion

        #region Form Methods and Functions

        private void Mailer_FormClosed(object sender, FormClosedEventArgs e) {
            LogDataManager.SaveLog(Contracts.MyUser.UserID, logType, logArea, "Mailer_FormClosed: End Mailer", false);
        }

        #endregion

        #region Methods

        public static void AddDictionayFields(Dictionary<string, string> myDict, string tKey, object tValue) {
            AddDictionayFields(myDict, tKey, tValue, null);
        }

        public static void AddDictionayFields(Dictionary<string, string> myDict, string tKey, object tValue, object defaultValue) {
            if (tValue != null) {
                myDict.Add(tKey, tValue.ToString());
            } else {
                if (defaultValue != null) {
                    myDict.Add(tKey, defaultValue.ToString());
                }
            }
        }

        private void CreatePDFDocuments() {
            string targetPath = this.txtTargetPath.Text;
            int mailID = 1;
            myOffice.Word.Application appWord = null;
            myOffice.Word.Document mDoc = null;
            appWord = TpTools.Office.GetWordApplication();

            try {
                foreach (MailObj mo in this.mailList) {
                    mDoc = appWord.Documents.Open(mo.WordDocument);
                    Tools.SaveAsPDF(mDoc);

                    ((myOffice.Word._Document)mDoc).Close(SaveChanges: true);

                    this.lblStep3.Text = mailID.ToString();
                    mailID++;
                }
            } catch (Exception ex) {
                LogDataManager.SaveLog(Contracts.MyUser.UserID, errType, logArea, "CreatePDFDocuments: " + ex.Message, true);
            } finally {
                this.btnStep4.Enabled = this.mailList.Count > 0;
                if (appWord != null & !this.wordStarted) {
                    ((myOffice.Word._Application)appWord).Quit();
                }
            }
        }

        private void CreateWordDocuments() {
            myOffice.Word.Application appWord = null;
            myOffice.Word.Document mDoc = null;
            appWord = TpTools.Office.GetWordApplication();
            appWord.Visible = false;
            try {
                bool wordStarted = Office.WordIsStarted();
                int mailID = 1;
                string vorlage = "";

                foreach (MailObj mo in this.mailList) {
                    vorlage = Path.Combine(this.txtTargetPath.Text, mo.Vorlage + ".dotx");
                    mDoc = Office.GetWordDocument(appWord, mo.WordDocument, vorlage);
                    if (File.Exists(mo.WordDocument)) {
                        File.Delete(mo.WordDocument);
                    }
                    mDoc.SaveAs2(FileName: mo.WordDocument);

                    #region Properties

                    if (Office.ExistingDocumentProperty(mDoc, "MailTo")) {
                        mDoc.CustomDocumentProperties["MailTo"].Delete();
                    }
                    mDoc.CustomDocumentProperties.Add("MailTo", false, MsoDocProperties.msoPropertyTypeString, mo.MailAdresse);

                    if (Office.ExistingDocumentProperty(mDoc, "Subject")) {
                        mDoc.CustomDocumentProperties["Subject"].Delete();
                    }
                    mDoc.CustomDocumentProperties.Add("Subject", false, MsoDocProperties.msoPropertyTypeString, this.txtSubject.Text);

                    if (Office.ExistingDocumentProperty(mDoc, "File1")) {
                        mDoc.CustomDocumentProperties["File1"].Delete();
                    }
                    mDoc.CustomDocumentProperties.Add("File1", false, MsoDocProperties.msoPropertyTypeString, mo.Datei.Replace(".docx", ".pdf"));

                    if (Office.ExistingDocumentProperty(mDoc, "TpDocType")) {
                        mDoc.CustomDocumentProperties["TpDocType"].Delete();
                    }
                    mDoc.CustomDocumentProperties.Add("TpDocType", false, Microsoft.Office.Core.MsoDocProperties.msoPropertyTypeNumber, Extensions.DocType.Mail);

                    #endregion


                    FillWordDocumentFields(appWord, mDoc, mo);
                    mDoc.Save();
                    if (this.chkOpen.Checked == false) {
                        ((myOffice.Word._Document)mDoc).Close(SaveChanges: true);
                    }
                    this.lblStep2.Text = mailID.ToString();
                    mailID++;
                }
            } catch (Exception ex) {
                LogDataManager.SaveLog(Contracts.MyUser.UserID, errType, logArea, "CreateWordDocuments: " + ex.Message, true);
            } finally {
                appWord.Visible = true;
                if (!this.chkOpen.Checked) {
                    this.btnStep3.Enabled = this.mailList.Count > 0;
                }

                if (appWord != null & !this.wordStarted) {
                    if (!this.chkOpen.Checked) {
                        ((myOffice.Word._Application)appWord).Quit();
                    }
                }
            }
        }

        private void FillWordDocumentFields(myOffice.Word.Application appWord, myOffice.Word.Document myDoc, MailObj mo) {
            Dictionary<string, string> myDict = new Dictionary<string, string>();
            AddDictionayFields(myDict, "Receipient", mo.Recipient);
            AddDictionayFields(myDict, "eMail", mo.MailAdresse);
            AddDictionayFields(myDict, "Anrede", mo.Grußformel + " " + mo.Anrede.Trim() + (mo.BerufsTitel != null ? " " + mo.BerufsTitel : "") + (mo.Titel != null ? " " + mo.Titel : "") + " " + mo.Nachname);
            AddDictionayFields(myDict, "Datei", mo.TpBereich +  mo.Datei  );
            AddDictionayFields(myDict, "Datum", DateTime.Today.ToString(Extensions.tpDateFormatExtern));

            SetWordBookmarks(myDoc, myDict);
        }

        private void GetMailingData(string mailSourceFile) {
            myOffice.Excel.Application exApp = Office.GetExcelApplication();
            myOffice.Excel.Workbook wb = null;
            myOffice.Excel.Worksheet sh = null;
            if (File.Exists(mailSourceFile) & !Tools.FileIsInUse(mailSourceFile)) {
                wb = exApp.Workbooks.Open(mailSourceFile);
            }

            sh = wb.Sheets[1];

            try {

                int startRow = 2;
                int mailID = 1;
                bool weiter = false;
                myOffice.Excel.Range r1;
                MailObj mailObj;
                
                while (weiter == false) {
                    mailObj = new MailObj();
                   
                    r1 = sh.Cells[startRow, "AQ"];
                    if (r1.Value != null) {
                        mailObj.MailAdresse = r1.Value;
                    } else {
                        r1 = sh.Cells[startRow, "P"];
                        mailObj.MailAdresse = r1.Value;
                    }

                    r1 = sh.Cells[startRow, "D"];
                    if (r1.Value != null) {
                        mailObj.Prefix = r1.Value.ToString();    
                    }

                    r1 = sh.Cells[startRow, "E"];
                    if (r1.Value != null) {
                        mailObj.Organisation = r1.Value.ToString();
                    }

                    r1 = sh.Cells[startRow, "F"];
                    if (r1.Value != null) {
                        mailObj.Zusatz = r1.Value.ToString();
                    }

                    r1 = sh.Cells[startRow, "G"];
                    if (r1.Value != null) {
                        int rf;
                        if (int.TryParse(r1.Value.ToString(), out rf)) {
                            mailObj.Rechtsform = Tools.GetRechtsform(rf);
                        }
                    }

                    

                    r1 = sh.Cells[startRow, "AC"];
                    if (r1.Value != null) {
                        mailObj.Anrede = (r1.Value == 1 ? "Herr" : "Frau");
                    }
                    r1 = sh.Cells[startRow, "AB"];
                    mailObj.Vorname = r1.Value;

                    r1 = sh.Cells[startRow, "AA"];
                    mailObj.Nachname = r1.Value;

                    //r1 = sh.Cells[startRow, "E"];
                    mailObj.Grußformel = "Guten Tag";

                    //r1 = sh.Cells[startRow, "F"];
                    //mailObj.BerufsTitel = r1.Value;

                    #region Person Titel

                    r1 = sh.Cells[startRow, "AD"];
                    if (r1.Value != null) {
                        int titel;
                        if (int.TryParse(r1.Value.ToString(), out titel)) {
                            mailObj.Titel = Tools.GetPersonenTitel(titel);
                        }
                    }

                    #endregion

                    #region Zusätze

                    r1 = sh.Cells[startRow, "BM"];
                    if (r1.Value != null) {
                        mailObj.Vorlage = r1.Value;
                    }

                    r1 = sh.Cells[startRow, "BN"];
                    if (r1.Value != null) {
                        mailObj.Datum = r1.Value;
                    }

                    r1 = sh.Cells[startRow, "BO"];
                    if (r1.Value != null) {
                        mailObj.Bereich = r1.Value.ToString();
                    }

                    r1 = sh.Cells[startRow, "BP"];
                    if (r1.Value != null) {
                        mailObj.Vz = r1.Value.ToString();
                    }

                    r1 = sh.Cells[startRow, "BQ"];
                    if (r1.Value != null) {
                        mailObj.SubBereich = r1.Value.ToString();
                    }

                    r1 = sh.Cells[startRow, "BR"];
                    if (r1.Value != null) {
                        mailObj.SubSubBereich = r1.Value.ToString();
                    }

                    r1 = sh.Cells[startRow, "BS"];
                    if (r1.Value != null) {
                        mailObj.Datei = r1.Value.ToString();
                        if (r1.Hyperlinks.Count > 0) {
                            r1.Hyperlinks.Delete();
                        }
                        r1.Hyperlinks.Add(r1, mailObj.TpFileName + ".docx", r1.Value.ToString() + ".docx");
                    }

                    #endregion

                    mailObj.WordDocument = mailObj.TpFileName + ".docx";
                    mailObj.PDFDocument = mailObj.TpFileName + ".pdf";
                    mailObj.TargetPath = Path.GetDirectoryName(mailObj.WordDocument) + @"\";

                    if (mailObj.MailAdresse != null && mailObj.MailAdresse.Length != 0) {
                        this.mailList.Add(mailObj);
                        this.lblStep1.Text = mailID.ToString();
                        mailID++;
                        startRow++;
                    }

                    if (mailObj.MailAdresse == null || mailObj.MailAdresse.Length == 0) {
                        weiter = true;
                    }
                }


            } catch (Exception ex) {
                LogDataManager.SaveLog(Contracts.MyUser.UserID, errType, logArea, "GetMailingData: " + ex.Message, true);
            } finally {
                this.lblStep1.Text = this.mailList.Count.ToString();
                this.btnStep2.Enabled = this.mailList.Count > 0;
                //this.btnStep3.Enabled = this.mailList.Count > 0;
                //this.btnStep4.Enabled = this.mailList.Count > 0;
                this.chkOpen.Enabled = this.mailList.Count > 0;
                wb.Save();
                wb.Close();

            }
        }

        private void SendMails() {

            myOffice.Outlook.Application olApp = Office.GetOutlookApplication();

            foreach (MailObj mo in this.mailList) {

                myOffice.Outlook.MailItem msg = olApp.CreateItem(myOffice.Outlook.OlItemType.olMailItem);
                if (msg == null) {
                    MessageBox.Show("Msg is null", "Error");
                }

                msg.To = mo.MailAdresse;
                msg.Subject = this.txtSubject.Text;
                msg.Attachments.Add(mo.PDFDocument);
                msg.TaskSubject = mo.PDFDocument.Replace(".pdf", ".msg");
                msg.DeleteAfterSubmit = true;
                ((myOffice.Outlook._MailItem)msg).Send();
            }

        }

        private void SetWordBookmarks(myOffice.Word.Document myDoc, Dictionary<string, string> myDict) {
            try {
                foreach (myOffice.Word.Bookmark bm in myDoc.Bookmarks) {
                    string tmName = bm.Name;
                    if (myDict.ContainsKey(tmName)) {
                        bm.Range.Text = myDict[tmName];
                    }
                }
            } catch (Exception ex) {
                LogDataManager.SaveLog(Contracts.MyUser.UserID, errType, logArea, "SetWordBookmarks: " + ex.Message, true);
            }
        }

        #endregion

        #region Functions

        



        #endregion

    }
}
